# How to git send-email

## Check if git is able to send-email ;-D

This command should output the manual, then git is ready to use send-email.

```bash
$ git send-email --help
```

If the previous command doesn't show a manual page you must install some dependencies. Check [installation options](https://git-send-email.io/) for your distribution.

## Install dependencies to use send-email, if not installed

Check the documentation specific to your distribution to do this.

```bash
$ sudo pacman -Syu --needed git perl-authen-sasl perl-io-socket-ssl
```

## Configure username and email for git to use it

Global git configuration:

```bash
$ git config --global user.name "mi nombre"
$ git config --global user.email "myemail@example.com"
```

To apply repository local configuration you use `--local` instead of `--global`:

```bash
$ cd your-git-repo/
$ git config --local user.name "mi nombre"
$ git config --local user.email "myemail@example.com"
```

You can select this for all configuration options you wish.

## Configure send-email options

Check your email provider server settings and fill these configuration options.

```bash
$ git config --global sendemail.smtpencryption tls
$ git config --global sendemail.smtpserver smtp.yourprovider.com
$ git config --global sendemail.smtpuser username@yourprovider.com
$ git config --global sendemail.smtpserverport 587
$ git config --global sendemail.smtppass "PASS/GOPASS/SHROUD"
```

The last option represents a security risk, because you must not save passwords in plain text. You must configure your [password store](https://www.passwordstore.org/) software to provide the password each time you use sendemail. 

## Configure git to use your password store provider

It is recomended to read [git credentials](https://git-scm.com/docs/gitcredentials) and [custom helpers](https://git-scm.com/docs/gitcredentials#_custom_helpers) to configure your helper to use your password storage system.

```bash
credential.helper=!f() { echo "password=$(pass email/username@yourprovider.com)"; }; f
```

## Send patches using send-email

Send the last parent of commit pointed by `HEAD` as a patch:

```bash
$ git send-email --to="~username/project-repo-name@maillist.gitprovider.com" HEAD^
```

You can add the previous setting permanently to your configuration and avoid writing it every time:

```bash
$ git config sendemail.to "~username/project-repo-name@maillist.gitprovider.com" 
$ git send-email HEAD^
```

Send last commit on current branch as a patch:

```bash
$ git send-email -1
```

Specify which commit to send as a patch:

```bash
$ git send-email -1 <commit sha1 object name>
```

### Generate patches using format-patch for later send-email

The `git format-patch` command is used to generate a series of patches in mbox format that you can use to send to a mailing list properly formatted. This turns each commit into an email message:

Generate a series of patches from previous commits, the `-M` option searches for renames:

```bash
$ git format-patch -M origin/master
0001-modify-something-on-project.patch
0002-modify-something-else-on-project.patch
```

Send patches to the email box:

```bash
$ git send-email *.patch
```

## Send multiple commits as patches

Send last 10 commmits as a patch, sending an explanation mail `--cover-letter` before the patches emails and open each for editing `--annotate` before sending all:

```bash
$ git send-email -10 --cover-letter --annotate
```

Send the last three commits as a patch:

```bash
$ git send-email HEAD~3
```

Send all commits since a particular commit as patch:

```bash
$ git send-email <commit sha1 object name>
```

Send second to last commit as a patch:

```bash
$ git send-email -1 HEAD^^
```

Send a "corrected" version of a commit as a patch:

```bash
$ git send-email -v2 -1
```

## Change the subject of the email

By default git sends the "[PATCH]" tag as a subject to each patch mail, you can change that with `--subject-prefix`:

```bash
$ git send-email -1 --subject-prefix = "PATCH finalrelease"
```

## Applying patches from email

Given that patches can be created from `git diff` or `format-patch` which `send-email` uses to format patches as mbox file format, there are two different ways to apply those patches: `git apply` and `git am`.

### Applying patches generated with diff

Check if a patch applies cleanly before applying it. If there is no output the patch applies cleanly:

```bash
$ git apply --check 0001-see-if-this-helps-the-gem.patch
error: patch failed: ticgit.gemspec:1
error: ticgit.gemspec: patch does not apply
```

Apply a patch generated with `git diff` and you saved it on tmp:

```bash
$ git apply /tmp/patch-ruby-client.patch
```

### Applying patches generated with format-patch

Technically, `git am` is built to read an mbox file, which is a simple, plain-text format for storing one or more email messages in one text file.

The `git am` command also creates a new commit when you apply the patch.

To apply a patch generated with format-patch:

```bash
$ git am 0001-limit-log-function.patch
Applying: Add limit to log function
```

Or you can pipe the mbox file generated from your email client to git am. In [aerc](https://aerc-mail.org/) you simply pipe the current email as:

```
:cd git-project-directory
:pipe git am
```

Check the applied patch with `git log`:

```bash
$ git log --pretty=fuller -1
```

If the `git am` command fails to apply the patch, it will print error messages and it won't generate the new commit.

## Other useful configuration options

Supress auto-cc of the sender to avoid including ourselves of the mail list:

```bash
$ git config sendemail.suppresscc self
```

## References

+ [git send-email](https://git-send-email.io)
+ [Git Commands - Email](https://git-scm.com/book/en/v2/Appendix-C%3A-Git-Commands-Email)
+ [Customizing Git - Git Configuration](https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration)
+ [Git Tools - Revision Selection](https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection)
+ [git credentials](https://git-scm.com/docs/gitcredentials)
+ [git-rev-parse](https://git-scm.com/docs/git-rev-parse#Documentation/git-rev-parse.txt-emltrevgtltngtemegemmaster3em)

## Interesting reads

+ [Email Driven Git](https://drewdevault.com/2018/07/02/Email-driven-git.html)
+ [Configuring aerc for git](https://drewdevault.com/2020/04/20/Configuring-aerc-for-git.html)
